#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <numeric>
#include <vector>
#include <map>
#include <iterator>
#include <functional>
//#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/timer.hpp>
#include <boost/shared_ptr.hpp>

using namespace std;
using namespace boost::lambda;

typedef map<string,int> SIM;

struct AddMap{
        SIM* mp;
	AddMap(SIM* mpp):mp(mpp){}
	void operator()(string s){
		++(*mp)[s];
	}
};

bool CountGreater( pair<string,int> p1, pair<string,int> p2)
{
	return p1.second > p2.second;
}

int main(int argc, char** argv){
	if( argc==1 ){
		cout<<"cmd file"<<endl;
		exit(1);
	}

	map<string,int> words;
	ifstream file(argv[1]);
	istream_iterator<string> in(file),endf;
	for_each(in,endf,AddMap(&words));

        pair<string,int> p;
        vector< pair<string,int> > V,V2;
        BOOST_FOREACH( p, words)
		V.push_back(p);

	words.clear();
	nth_element( V.begin(), V.begin()+10, V.end(),CountGreater );
	V2.assign(V.begin(), V.begin()+10);
	sort( V2.begin(), V2.end(), CountGreater);

	V.clear();

        BOOST_FOREACH( p, V2 ){
	    cout.setf(ios::right);
	    cout<<setw(10)<<setfill('_')<<p.first<<"  ->  "<<setw(10)<<p.second<<endl;
	}
	return 0;
}
